package com.ifacebox.face.track.ui;

import com.ifacebox.face.track.utils.ThreadUtils;

import javax.swing.*;
import java.awt.*;
import java.util.Objects;

/**
 * @author znn
 */
public class FaceLoadingDialog extends JDialog {
    private static final ImageIcon LOADING = new ImageIcon(Objects.requireNonNull(FaceLoadingDialog.class.getResource("/loading.png")));
    private JProgressBar progressBar;
    private String progressString;

    public FaceLoadingDialog() {
        super.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        super.setSize(LOADING.getIconWidth(), LOADING.getIconHeight());
        super.setBackground(new Color(201, 202, 202));
        super.setLayeredPane(new JLayeredPane() {{
            this.add(new JLabel(LOADING) {{
                this.setSize(FaceLoadingDialog.this.getSize());
            }}, JLayeredPane.DEFAULT_LAYER);
            this.add(new JPanel() {{
                this.setOpaque(false);
                this.setLayout(new BorderLayout());
                this.setSize(FaceLoadingDialog.this.getSize());
                this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
                this.add(progressBar = new JProgressBar() {{
                    this.setStringPainted(true);
                }}, BorderLayout.SOUTH);
            }}, JLayeredPane.MODAL_LAYER);
        }});
        super.setUndecorated(true);
        super.setAlwaysOnTop(true);
        super.setResizable(false);
        super.setLocationRelativeTo(null);
    }

    public void setValue(int min, int max) {
        this.progressBar.setMinimum(min);
        this.progressBar.setMaximum(max);
        this.progressBar.setValue(0);
    }

    public void show(String progressString, Callback callback) {
        this.progressString = progressString;
        this.progressBar.setIndeterminate(true);
        this.progressBar.setString(progressString);
        if (super.isVisible()) {
            super.setVisible(false);
        } else {
            super.setVisible(true);
            ThreadUtils.runThread(() -> {
                try {
                    callback.call();
                } catch (Exception e) {
                    callback.error(e);
                } finally {
                    SwingUtilities.invokeLater(() -> super.setVisible(false));
                }
            });
        }
    }

    public void call(String progressString, Callback callback) throws Exception {
        this.call(progressString);
        callback.call();
    }

    public void call(String progressString) {
        this.progressString = progressString;
        SwingUtilities.invokeLater(() -> {
            this.progressBar.setIndeterminate(false);
            this.progressBar.setValue(this.progressBar.getValue() + 1);
            this.progressBar.setString(String.format(" %s(%.0f%%) ", this.progressString
                    , (float) this.progressBar.getValue() / (float) this.progressBar.getMaximum() * 100));
        });
    }

    interface Callback {
        /**
         * 回调
         *
         * @throws Exception 异常
         */
        void call() throws Exception;

        /**
         * 异常回调
         *
         * @param err 异常
         */
        default void error(Exception err) {
        }
    }
}
